package com.horay.springclouddemo.provider.hystrix.service.impl;

import com.horay.springclouddemo.model.hystrix.Hystrix;
import com.horay.springclouddemo.model.hystrix.HystrixDTO;
import com.horay.springclouddemo.provider.hystrix.service.HystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

/**
 * 豪猪业务服务实现类
 *
 * @author heyingcheng
 * @date 2020/3/21 14:19
 */
@Slf4j
@Service
public class HystrixServiceImpl implements HystrixService {

    @Value("${server.port}")
    private int port;

    /**
     * 新增豪猪
     *
     * @param hystrix
     * @return boolean
     * @author heyingcheng
     * @date 2020/3/21 14:17
     */
    @Override
    @HystrixCommand(fallbackMethod = "createHystrixFallbackHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public boolean createHystrix(Hystrix hystrix) {
        int i = 1 / 0;
        log.info("{}.createHystrix, port:[{}], hystrix:[{}]", this.getClass().getName(), port, hystrix);
        return true;
    }

    /**
     * 新增豪猪超时处理程序
     *
     * @param hystrix
     * @return boolean
     * @author heyingcheng
     * @date 2020/3/21 14:17
     */
    private boolean createHystrixFallbackHandler(Hystrix hystrix) {
        log.info("{}.createHystrixFallbackHandler, port:[{}], hystrix:[{}]", this.getClass().getName(), port, hystrix);
        return true;
    }

    /**
     * 获取豪猪
     *
     * @param id
     * @return com.horay.springclouddemo.provider.hystrix.model.Hystrix
     * @author heyingcheng
     * @date 2020/3/21 14:17
     */
    @HystrixCommand(fallbackMethod = "getHystrixCircuitBreakerFallback", commandProperties = {
            // 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            // 请求次数
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            // 时间窗口期
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
            // 失败率达到多少后跳阙
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
    })
    @Override
    public Hystrix getHystrix(Integer id) {
        log.info("{}.getHystrix, port:[{}], id:[{}]", this.getClass().getName(), port, id);
        if (id > 0) {
            return new Hystrix(id);
        } else {
            throw new RuntimeException();
        }
    }

    private Hystrix getHystrixCircuitBreakerFallback(Integer id) {
        log.info("{}.getHystrixCircuitBreakerFallback, port:[{}], id:[{}]", this.getClass().getName(), port, id);
        return new Hystrix(-1);
    }

    /**
     * 获取豪猪集合
     *
     * @param hystrixDTO
     * @return java.util.List<com.horay.springclouddemo.provider.hystrix.model.Hystrix>
     * @author heyingcheng
     * @date 2020/3/21 14:18
     */
    @Override
    public List<Hystrix> getHystrixs(HystrixDTO hystrixDTO) {
        log.info("{}.getHystrixs, port:[{}], hystrixDTO:[{}]", this.getClass().getName(), port, hystrixDTO);
        return Collections.emptyList();
    }

    /**
     * 更新豪猪
     *
     * @param hystrix
     * @return boolean
     * @author heyingcheng
     * @date 2020/3/21 14:18
     */
    @Override
    public boolean updateHystrix(Hystrix hystrix) {
        log.info("{}.updateHystrix, port:[{}], hystrix:[{}]", this.getClass().getName(), port, hystrix);
        throw new RuntimeException();
    }

    /**
     * 删除豪猪
     *
     * @param id
     * @return boolean
     * @author heyingcheng
     * @date 2020/3/21 14:19
     */
    @HystrixCommand(fallbackMethod = "deleteHystrixFallbackHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    @Override
    public boolean deleteHystrix(Integer id) {
        log.info("{}.deleteHystrix, port:[{}], id:[{}]", this.getClass().getName(), port, id);
        return true;
    }

    private boolean deleteHystrixCircuitBreakerFallback(Integer id) {
        log.info("deleteHystrixCircuitBreakerFallback");
        return true;
    }

}
